package com.ifnk.portaljava.controller;

import com.ifnk.portaljava.dapWeb.hlyt.servlet.CallTraceServlet;
import com.ifnk.portaljava.entity.QueryInput;
import com.ifnk.portaljava.entity.SuccessResult;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("api/packet")
public class PacketController {
    @Autowired
    HttpServletRequest request;

    private final String CDRKEY = "all";
    private static int XDRLEN = 8;
    public static ConcurrentHashMap<String, List<byte[]>> pktByteMap = new ConcurrentHashMap<>();

    // 测试用
    @GetMapping("detail")
    public SuccessResult<String> getDetail() {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("bash", "-c", "tshark -r ~/pcap/summary/bd51334d1da743da9091910e55e40fb2/all/all.pcap -T pdml | fxparser");
//        processBuilder.command("bash", "-c", dudu);
        try {
            String output = getOutput(processBuilder);
            return new SuccessResult<>(output);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    // 测试用
    @GetMapping("summary")
    public SuccessResult<String> getSummary() {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("bash", "-c", "tshark -r ~/pcap/summary/bd51334d1da743da9091910e55e40fb2/all/all.pcap -T tabs");
        try {
            String output = getOutput(processBuilder);
            return new SuccessResult<>(output);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    // 测试用
    @GetMapping("clear")
    public SuccessResult<String> clear() {
        CallTraceServlet.removeStoppedClient();
        return new SuccessResult<String>("清除成功");
    }

    // 下载 pcap 文件
    @GetMapping("downloadPcap/{id}")
    public void downloadPcap(@PathVariable String id, HttpServletResponse response) {
        ResourceBundle localResource = ResourceBundle.getBundle("Socket", Locale.ENGLISH);
        String pcapfilepath = localResource.getString("pacpfilepath");
        String path = Paths.get(pcapfilepath, "summary", id, "all", "all.pcap").toString();
        File file = new File(path);
        if (!file.exists()) throw new RuntimeException("文件不存在!下载失败!" + path);

        try {
            Files.copy(file.toPath(), response.getOutputStream());
            String mimeType = URLConnection.guessContentTypeFromName(file.getName());
            String contentDisposition = String.format("attachment; filename=%s", file.getName());
            int fileSize = Long.valueOf(file.length()).intValue();

            response.setContentType(mimeType);
            response.setHeader("Content-Disposition", contentDisposition);
            response.setContentLength(fileSize);
        } catch (FileNotFoundException e) {
            System.out.println(e);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    // 测试用
    @GetMapping("hex")
    public SuccessResult<String> getHex() {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("bash", "-c", "tshark -r ~/pcap/summary/bd51334d1da743da9091910e55e40fb2/all/all.pcap -T jsonraw");
        try {
            String output = getOutput(processBuilder);
            return new SuccessResult<>(output);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static String getOutput(ProcessBuilder processBuilder) throws IOException {
        Process process = processBuilder.start();
        return IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8);
    }

    @GetMapping("query")
    public SuccessResult<String> query(QueryInput input) {
        // 向proxy 服务器发送请求
        //一个RawQuery过程由 WWW_RQ_RAW_QUERY 建立，WWW_RQ_RAW_QUERY_COMPLETE 结束，中间包含多个 WWW_RQ_RAWDATA构成
//        String cmd = "WWW_RQ_RAW_QUERY";
        String clientId = input.getClientId();
        String packetUniqueId = input.getPacketUniqueId();
        HttpSession session = request.getSession();

        CallTraceServlet callTraceServlet = new CallTraceServlet();
        // 启动一个新的 client
        callTraceServlet.queryqueryCallTraceStart(clientId, session, "172.168.10.52", 18000);

        String opType = "query"; // 分 query 和 imsearch 查询
        String[] str_cdrs = input.getCdrStrs().split(",");
        System.out.println("str_cdrs = " + Arrays.toString(str_cdrs));
        String[] str_times = new String[]{"1650807526"};
        String str_protocol_RQ = "1";
        String str_svrid = "1";

        int start_ts = 1650807526;
        long[] cdrs = new long[str_cdrs.length];
        long[] times = new long[str_times.length];

        for (int i = 0; i < str_cdrs.length; i++) {
            cdrs[i] = (Long.parseLong(str_cdrs[i]));
        }
        callTraceServlet.XDRLEN = 16;

        System.out.println("cdrs = " + Arrays.toString(cdrs));
        System.out.println("times = " + Arrays.toString(times));


        int svrid = Integer.parseInt(str_svrid);

        int protocol_RAW_QUERY = Integer.parseInt(str_protocol_RQ);

        try {
            String s = callTraceServlet.queryQuery(opType, clientId, str_cdrs[0], (byte) protocol_RAW_QUERY, svrid, cdrs, times, start_ts);
            // 走到这里说明发送成功了
            System.out.println("s = " + s);
            return new SuccessResult<>(s);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}